//--------------------------------------------------------------------------------
// This file is part of the Windows Workflow Foundation Sample Code
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// This source code is intended only as a supplement to Microsoft
// Development Tools and/or on-line documentation.  See these other
// materials for detailed information regarding Microsoft code samples.
// 
// THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//--------------------------------------------------------------------------------

using System;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.Activities.Rules;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Drawing.Design;
using Microsoft.Samples.Workflow.UI.Design;

namespace Microsoft.Samples.Workflow.UI
{
    [System.ComponentModel.ToolboxItem(false)]
    public class Transition : DependencyObject
    {
        public static readonly DependencyProperty TargetProperty = DependencyProperty.Register("Target", typeof(string), typeof(Transition), new PropertyMetadata(null, DependencyPropertyOptions.Metadata, new Attribute[] { new ValidationOptionAttribute(ValidationOption.Required) }));
        public static readonly DependencyProperty ConditionProperty = DependencyProperty.Register("Condition", typeof(ActivityCondition), typeof(Transition), new PropertyMetadata(DependencyPropertyOptions.Metadata));
        public static readonly DependencyProperty ValidationRulesProperty = DependencyProperty.Register("ValidationRules", typeof(RuleSetReference), typeof(Transition), new PropertyMetadata(DependencyPropertyOptions.Metadata));

        [NonSerialized]
        private Activity activity;

        public Transition()
        {
        }

        public Transition(string target)
        {
            this.Target = target;
        }

        [MergableProperty(false)]
        [SRCategory(SR.Navigation)]
        [SRDescription(SR.TargetDescription)]
        [Editor(typeof(TransitionTargetEditor), typeof(UITypeEditor))]
        public string Target
        {
            get
            {
                return this.GetValue(TargetProperty) as string;
            }
            set
            {
                this.SetValue(TargetProperty, value);
            }
        }

        [MergableProperty(false)]
        [SRCategory(SR.Navigation)]
        [SRDescription(SR.ConditionDescription)]
        public ActivityCondition Condition
        {
            get
            {
                return this.GetValue(ConditionProperty) as ActivityCondition;
            }
            set
            {
                this.SetValue(ConditionProperty, value);
            }
        }

        [MergableProperty(false)]
        [SRCategory(SR.Navigation)]
        public RuleSetReference ValidationRules
        {
            get
            {
                return (RuleSetReference)base.GetValue(ValidationRulesProperty);
            }
            set
            {
                base.SetValue(ValidationRulesProperty, value);
            }
        }

        //this is needed for the collection editor to show a better name
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public string Name
        {
            get
            {
                return (!string.IsNullOrEmpty(this.Target)) ? "Transition to " + this.Target : "Transition not specified yet";
            }
        }

        internal Activity Activity
        {
            get
            {
                return this.activity;
            }
            set
            {
                this.activity = value;
            }
        }

        // Evaluates this possible transition.  Transition.Condition == null -> true
        internal string Evaluate(Activity ownerActivity, ActivityExecutionContext context)
        {
            string result = null;
            if (this.Condition == null ||
                this.Condition.Evaluate(ownerActivity, context))
            {
                result = this.Target;
                if (this.ValidationRules != null)
                {
                    Activity declaringActivity = Helpers.GetDeclaringActivity(ownerActivity);
                    if (declaringActivity == null)
                    {
                        declaringActivity = Helpers.GetRootActivity(ownerActivity);
                    }

                    RuleDefinitions ruleDefinitions = (RuleDefinitions)declaringActivity.GetValue(RuleDefinitions.RuleDefinitionsProperty);
                    if (ruleDefinitions != null)
                    {
                        RuleSet ruleSet = ruleDefinitions.RuleSets[this.ValidationRules.RuleSetName];
                        if (ruleSet != null)
                        {
                            RuleValidation validation = new RuleValidation(declaringActivity.GetType(), null);
                            RuleExecution ruleExecutionContext = new RuleExecution(validation, declaringActivity, context);
                            ruleSet.Execute(ruleExecutionContext);
                        }
                    }
                }
            }

            return result;
        }
    }
}

